﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using élénkPróbája.extentions;
using élénkPróbája.Test.dto;
using élénkPróbája.Test.extention;
using élénkPróbája.validators;

namespace élénkPróbája.Test
{
    [TestClass]
    public class ForEachRuleTests
    { 
        [TestMethod]
        public void Executes_rule_for_each_item_in_collection()
        {
            var validator = new TestValidator {
                v => v.RuleForEach(x => x.RoutingNames).NotNull()
            };

            var company = new Company()
            {
                RoutingNames = new[] { null, "foo", null }
            };

            var result = validator.Validate(company);
            result.Errors.Count.ShouldEqual(2);
        }

        [TestMethod]
        public void Correctly_gets_collection_indicies()
        {
            var validator = new TestValidator {
                v => v.RuleForEach(x => x.RoutingNames).NotNull()
            };

            var company = new Company()
            {
                RoutingNames = new[] { null, "foo", null }
            };

            var result = validator.Validate(company);
            result.Errors[0].PropertyName.ShouldEqual("RoutingNames[0]");
            result.Errors[1].PropertyName.ShouldEqual("RoutingNames[2]");
        }

        [TestMethod]
        public void Executes_rule_for_each_item_in_collection_async()
        {
            var validator = new TestValidator {
                v => v.RuleForEach(x => x.RoutingNames).SetValidator(new MyAsyncNotNullValidator())
            };

            var company = new Company()
            {
                RoutingNames = new[] { null, "foo", null }
            };

            var result = validator.ValidateAsync(company).Result;
            result.Errors.Count.ShouldEqual(2);
        }

        [TestMethod]
        public void Correctly_gets_collection_indicies_async()
        {
            var validator = new TestValidator {
                v => v.RuleForEach(x => x.RoutingNames).SetValidator(new MyAsyncNotNullValidator())
            };

            var company = new Company()
            {
                RoutingNames = new[] { null, "foo", null }
            };

            var result = validator.ValidateAsync(company).Result;
            result.Errors[0].PropertyName.ShouldEqual("RoutingNames[0]");
            result.Errors[1].PropertyName.ShouldEqual("RoutingNames[2]");
        }
        [TestMethod]
        public void Nested_collection_for_null_property_should_not_throw_null_reference()
        {
            var validator = new InlineValidator<request>();
            validator.When(r => r.person != null, () => {
                validator.RuleForEach(x => x.person.NickNames).NotNull();
            });

            var result = validator.Validate(new request());
            result.Errors.Count.ShouldEqual(0);
        }
#region InternalClasses
        class request
        {
            public Person person = null;
        }

        private class MyAsyncNotNullValidator : PopulatedValidator
        {
            public override bool IsAsync { get { return true; } }
        }
#endregion
    }
}